//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "AmylogenicData.h"

#include <string.h>
#include <stdlib.h>

#include <iostream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
AmylogenicData::AmylogenicData() {
  
  this->id                              = new String();
  this->description                     = new String();

  this->sequence                        = new String();
  this->sequencesShuffle                = new String();

  this->amylogenicRegions               = new String();

  this->numberAmylogenicRegions         = -1;
  this->sizeAmylogenicRegions           = 0;
  this->percentAmylogenicRegions        = 0;

  this->amylogenicRegionsShuffle        = new String();

  this->numberAmylogenicRegionsShuffle  = -1;
  this->sizeAmylogenicRegionsShuffle    = 0;
  this->percentAmylogenicRegionsShuffle = 0;
  
  for (int i = 0; i < AMOUNTAA; i++) frequencyAA[i] = 0;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
AmylogenicData::AmylogenicData(const AmylogenicData& amylogenicData) {

  this->id                                  = new String(amylogenicData.id);
  this->description                         = new String(amylogenicData.description);

  this->sequence                            = new String(amylogenicData.sequence);
  this->sequencesShuffle                    = new String(amylogenicData.sequencesShuffle);

  this->amylogenicRegions                   = new String(amylogenicData.amylogenicRegions);

  this->numberAmylogenicRegions             = amylogenicData.numberAmylogenicRegions;
  this->sizeAmylogenicRegions               = amylogenicData.sizeAmylogenicRegions;
  this->percentAmylogenicRegions            = amylogenicData.percentAmylogenicRegions;

  this->amylogenicRegionsShuffle            = new String(amylogenicData.amylogenicRegionsShuffle);

  this->numberAmylogenicRegionsShuffle      = amylogenicData.numberAmylogenicRegionsShuffle;
  this->sizeAmylogenicRegionsShuffle        = amylogenicData.sizeAmylogenicRegionsShuffle;
  this->percentAmylogenicRegionsShuffle     = amylogenicData.percentAmylogenicRegionsShuffle;

  for (int i = 0; i < AMOUNTAA; i++) this->frequencyAA[i] = 0;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
AmylogenicData::AmylogenicData(const AmylogenicData* amylogenicData) {

  this->id                                  = new String(amylogenicData->id);
  this->description                         = new String(amylogenicData->description);

  this->sequence                            = new String(amylogenicData->sequence);
  this->sequencesShuffle                    = new String(amylogenicData->sequencesShuffle);

  this->amylogenicRegions                   = new String(amylogenicData->amylogenicRegions);

  this->numberAmylogenicRegions             = amylogenicData->numberAmylogenicRegions;
  this->sizeAmylogenicRegions               = amylogenicData->sizeAmylogenicRegions;
  this->percentAmylogenicRegions            = amylogenicData->percentAmylogenicRegions;

  this->amylogenicRegionsShuffle            = new String(amylogenicData->amylogenicRegionsShuffle);

  this->numberAmylogenicRegionsShuffle      = amylogenicData->numberAmylogenicRegionsShuffle;
  this->sizeAmylogenicRegionsShuffle        = amylogenicData->sizeAmylogenicRegionsShuffle;
  this->percentAmylogenicRegionsShuffle     = amylogenicData->percentAmylogenicRegionsShuffle;

  for (int i = 0; i < AMOUNTAA; i++) this->frequencyAA[i] = 0;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
AmylogenicData::~AmylogenicData() {
  
  if (this->id)                               delete this->id;
  if (this->description)                      delete this->description;

  if (this->sequence)                         delete this->sequence;
  if (this->sequencesShuffle)                 delete this->sequencesShuffle;

  if (this->amylogenicRegions)                delete this->amylogenicRegions;
  if (this->amylogenicRegionsShuffle)         delete this->amylogenicRegionsShuffle;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::Id(String *id) {
  if (id) this->id->In(id);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::Id(char *id) {
  if (id) this->id->In(id);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::Description(String *description) {
  if (description) this->description->In(description);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::Description(char *description) {
  if (description) this->description->In(description);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::Sequence(String *sequence) {
  if (sequence) this->sequence->In(sequence);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::Sequence(char *sequence) {
  if (sequence) this->sequence->In(sequence);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::SequencesShuffle(String* sequencesShuffle) {
  if (sequencesShuffle) this->sequencesShuffle->In(sequencesShuffle);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::AmylogenicRegions(String* amylogenicRegions) {
  if (amylogenicRegions) this->amylogenicRegions->In(amylogenicRegions);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::AmylogenicRegions(char* amylogenicRegions) {
  if (amylogenicRegions) this->amylogenicRegions->In(amylogenicRegions);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::NumberAmylogenicRegions(int numberAmylogenicRegions) {
  if (numberAmylogenicRegions >= 0) this->numberAmylogenicRegions = numberAmylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::SizeAmylogenicRegions(int sizeAmylogenicRegions) {
  if (sizeAmylogenicRegions >= 0) this->sizeAmylogenicRegions = sizeAmylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::PercentAmylogenicRegions(double percentAmylogenicRegions) {
  if (percentAmylogenicRegions >= 0 && percentAmylogenicRegions <= 100)
    this->percentAmylogenicRegions = percentAmylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::AmylogenicRegionsShuffle(String* amylogenicRegionsShuffle) {
  if (amylogenicRegionsShuffle) this->amylogenicRegionsShuffle->In(amylogenicRegionsShuffle);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::NumberAmylogenicRegionsShuffle(int numberAmylogenicRegionsShuffle) {
  this->numberAmylogenicRegionsShuffle = numberAmylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::SizeAmylogenicRegionsShuffle(int sizeAmylogenicRegionsShuffle) {
  this->sizeAmylogenicRegionsShuffle = sizeAmylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void AmylogenicData::PercentAmylogenicRegionsShuffle(double percentAmylogenicRegionsShuffle) {
  if (percentAmylogenicRegionsShuffle >= 0 && percentAmylogenicRegionsShuffle <= 100)
    this->percentAmylogenicRegionsShuffle = percentAmylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* AmylogenicData::Id(void) {
  return this->id;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* AmylogenicData::Description(void) {
  return this->description;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* AmylogenicData::Sequence(void) {
  return this->sequence;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* AmylogenicData::SequencesShuffle(void) {
  return this->sequencesShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* AmylogenicData::AmylogenicRegions(void) {
  return this->amylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int AmylogenicData::NumberAmylogenicRegions(void) {
  return this->numberAmylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int AmylogenicData::SizeAmylogenicRegions(void) {
  return this->sizeAmylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double AmylogenicData::PercentAmylogenicRegions(void) {
  return this->percentAmylogenicRegions;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* AmylogenicData::AmylogenicRegionsShuffle(void) {
  return this->amylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int AmylogenicData::NumberAmylogenicRegionsShuffle(void) {
  return this->numberAmylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int AmylogenicData::SizeAmylogenicRegionsShuffle(void) {
  return this->sizeAmylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double AmylogenicData::PercentAmylogenicRegionsShuffle(void) {
  return this->percentAmylogenicRegionsShuffle;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double* AmylogenicData::FrequencyAA(void) {
  return this->frequencyAA;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::ReadSequenceFromFASTA(String* lines) {

  if (!lines) return false;

  char* temporalId  = strtok(lines->Out(), "\n\r");
  char* temporalSeq = strtok(NULL, "\n\r");

  if (temporalId)  this->id->In((temporalId[0] == '>')?temporalId + 1:temporalId);
  if (temporalSeq) this->sequence->In(temporalSeq);

  this->sequence->RTrim();

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::ReadSequenceFromFASTA(char* lines) {

  if (!lines) return false;

  char* temporalId  = strtok(lines, "\n\r");
  char* temporalSeq = strtok(NULL, "\n\r");

  if (temporalId)  this->id->In((temporalId[0] == '>')?temporalId + 1:temporalId);
  if (temporalSeq) this->sequence->In(temporalSeq);

  this->sequence->RTrim();

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::AddSequenceShufleFromFASTA(String* lines) {

  if (!lines) return false;

  char* temporalId  = strtok(lines->Out(), "\n\r");
  char* temporalSeq = strtok(NULL, "\n\r");

  if (temporalId)  this->description->In((temporalId[0] == '>')?temporalId + 1:temporalId);
  if (temporalSeq) this->sequencesShuffle->In(temporalSeq);

  this->sequencesShuffle->RTrim();

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::AddSequenceShufleFromFASTA(char* lines) {

  if (!lines) return false;

  char* temporalId  = strtok(lines, "\n\r");
  char* temporalSeq = strtok(NULL, "\n\r");

  if (temporalId)  this->description->In((temporalId[0] == '>')?temporalId + 1:temporalId);
  if (temporalSeq) this->sequencesShuffle->In(temporalSeq);

  this->sequencesShuffle->RTrim();

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::ReadAmylogenicRegionsSequence(String* lines) {

  if (!lines) return false;

  char* temporalId = strtok(lines->Out(), "#\n\r");
  temporalId       = strtok(NULL,         "#\n\r");

  if (temporalId)  this->amylogenicRegions->In(temporalId);
  else return false;
  
  this->amylogenicRegions->RTrim();

  temporalId = strtok(NULL,         "#\n\r");
  temporalId = strtok(temporalId,   ",\n\r");
  if (temporalId) this->numberAmylogenicRegions  = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->sizeAmylogenicRegions    = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->percentAmylogenicRegions = atof(temporalId);
  else return false;

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::ReadAmylogenicRegionsSequence(char* lines) {

  if (!lines) return false;

  char* temporalId = strtok(lines, "#\n\r");
  temporalId       = strtok(NULL,         "#\n\r");

  if (temporalId)  this->amylogenicRegions->In(temporalId);
  else return false;
  
  this->amylogenicRegions->RTrim();

  temporalId = strtok(NULL,         "#\n\r");
  temporalId = strtok(temporalId,   ",\n\r");
  if (temporalId) this->numberAmylogenicRegions  = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->sizeAmylogenicRegions    = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->percentAmylogenicRegions = atof(temporalId);
  else return false;

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::AddAmylogenicRegionsSequenceShuffle(String* lines) {
  
  if (!lines) return false;

  char* temporalId = strtok(lines->Out(), "#\n\r");
  temporalId       = strtok(NULL,         "#\n\r");

  if (temporalId)  this->amylogenicRegionsShuffle->In(temporalId);
  else return false;
  
  this->amylogenicRegionsShuffle->RTrim();

  temporalId = strtok(NULL,         "#\n\r");
  temporalId = strtok(temporalId,   ",\n\r");
  if (temporalId) this->numberAmylogenicRegionsShuffle  = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->sizeAmylogenicRegionsShuffle    = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->percentAmylogenicRegionsShuffle = atof(temporalId);
  else return false;

  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool AmylogenicData::AddAmylogenicRegionsSequenceShuffle(char* lines) {
  
  if (!lines) return false;

  char* temporalId = strtok(lines, "#\n\r");
  temporalId       = strtok(NULL,         "#\n\r");

  if (temporalId)  this->amylogenicRegionsShuffle->In(temporalId);
  else return false;
  
  this->amylogenicRegionsShuffle->RTrim();

  temporalId = strtok(NULL,         "#\n\r");
  temporalId = strtok(temporalId,   ",\n\r");
  if (temporalId) this->numberAmylogenicRegionsShuffle  = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->sizeAmylogenicRegionsShuffle    = atoi(temporalId);
  else return false;

  temporalId = strtok(NULL,   ",\n\r");
  if (temporalId) this->percentAmylogenicRegionsShuffle = atof(temporalId);
  else return false;

  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double* AmylogenicData::GetFrequencyAASequence(void) {

  for (int i = 0; i < AMOUNTAA; i++) this->frequencyAA[i] = 0;

  //A = 0, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y
  for (int i = 0; i < this->sequence->Length(); i++)
    switch (this->sequence->Out()[i]) {
      case 'A' : this->frequencyAA[A]++; break;
      case 'C' : this->frequencyAA[C]++; break;
      case 'D' : this->frequencyAA[D]++; break;
      case 'E' : this->frequencyAA[E]++; break;
      case 'F' : this->frequencyAA[F]++; break;
      case 'G' : this->frequencyAA[G]++; break;
      case 'H' : this->frequencyAA[H]++; break;
      case 'I' : this->frequencyAA[I]++; break;
      case 'K' : this->frequencyAA[K]++; break;
      case 'L' : this->frequencyAA[L]++; break;
      case 'M' : this->frequencyAA[M]++; break;
      case 'N' : this->frequencyAA[N]++; break;
      case 'P' : this->frequencyAA[P]++; break;
      case 'Q' : this->frequencyAA[Q]++; break;
      case 'R' : this->frequencyAA[R]++; break;
      case 'S' : this->frequencyAA[S]++; break;
      case 'T' : this->frequencyAA[T]++; break;
      case 'V' : this->frequencyAA[V]++; break;
      case 'W' : this->frequencyAA[W]++; break;
      case 'Y' : this->frequencyAA[Y]++; break;
      case 'X' : this->frequencyAA[X]++; break;
      default  : break;
    }

  for (int i = 0; i < AMOUNTAA; i++) 
    this->frequencyAA[i] /= ((double)this->sequence->Length());

  return this->frequencyAA;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double* AmylogenicData::GetFrequencyAASequenceShuffle(void) {

  for (int i = 0; i < AMOUNTAA; i++) this->frequencyAA[i] = 0;

  //A = 0, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y
  for (int i = 0; i < this->sequencesShuffle->Length(); i++)
    switch (this->sequencesShuffle->Out()[i]) {
      case 'A' : this->frequencyAA[A]++; break;
      case 'C' : this->frequencyAA[C]++; break;
      case 'D' : this->frequencyAA[D]++; break;
      case 'E' : this->frequencyAA[E]++; break;
      case 'F' : this->frequencyAA[F]++; break;
      case 'G' : this->frequencyAA[G]++; break;
      case 'H' : this->frequencyAA[H]++; break;
      case 'I' : this->frequencyAA[I]++; break;
      case 'K' : this->frequencyAA[K]++; break;
      case 'L' : this->frequencyAA[L]++; break;
      case 'M' : this->frequencyAA[M]++; break;
      case 'N' : this->frequencyAA[N]++; break;
      case 'P' : this->frequencyAA[P]++; break;
      case 'Q' : this->frequencyAA[Q]++; break;
      case 'R' : this->frequencyAA[R]++; break;
      case 'S' : this->frequencyAA[S]++; break;
      case 'T' : this->frequencyAA[T]++; break;
      case 'V' : this->frequencyAA[V]++; break;
      case 'W' : this->frequencyAA[W]++; break;
      case 'Y' : this->frequencyAA[Y]++; break;
      case 'X' : this->frequencyAA[X]++; break;
      default  : break;
    }

  for (int i = 0; i < AMOUNTAA; i++) 
    this->frequencyAA[i] /= (double)this->sequencesShuffle->Length();
      
  return this->frequencyAA;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
AmylogenicData AmylogenicData::operator=(const AmylogenicData& AmylogenicData) {
  
  this->id->In(AmylogenicData.id);
  this->description->In(AmylogenicData.description);

  this->sequence->In(AmylogenicData.sequence);
  *(this->sequencesShuffle)               = *(AmylogenicData.sequencesShuffle);

  this->amylogenicRegions->In(AmylogenicData.amylogenicRegions);

  this->numberAmylogenicRegions           = AmylogenicData.numberAmylogenicRegions;
  this->sizeAmylogenicRegions             = AmylogenicData.sizeAmylogenicRegions;
  this->percentAmylogenicRegions          = AmylogenicData.percentAmylogenicRegions;

  this->amylogenicRegionsShuffle->In(AmylogenicData.amylogenicRegionsShuffle);

  this->numberAmylogenicRegionsShuffle    = AmylogenicData.numberAmylogenicRegionsShuffle;
  this->sizeAmylogenicRegionsShuffle      = AmylogenicData.sizeAmylogenicRegionsShuffle;
  this->percentAmylogenicRegionsShuffle   = AmylogenicData.percentAmylogenicRegionsShuffle;

  for (int i = 0; i < AMOUNTAA; i++) this->frequencyAA[i] = AmylogenicData.frequencyAA[i];
  
  return *this;
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
